package com.gqr.deadlock;

import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Copyright (C), 2020-2024,gqr
 * FileName:TryLockDeadLock
 * author:guqingrong
 * Date:2024-05-05 13:31
 * Description:用tryLock来避免死锁
 * History:
 * <author>    <time>    <version>    <desc>
 * 作者姓名     修改时间     版本号        描述
 */
public class TryLockDeadLock implements Runnable {
    static Lock lock1 = new ReentrantLock();
    static Lock lock2 = new ReentrantLock();
    int flag=1;

    public static void main(String[] args) {
        TryLockDeadLock r1 = new TryLockDeadLock();
        TryLockDeadLock r2 = new TryLockDeadLock();
        r1.flag=1;
        r2.flag=0;
        new Thread(r1).start();
        new Thread(r2).start();
    }
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if(flag==1){
                try {
                    if(lock1.tryLock(800, TimeUnit.MILLISECONDS)){
                        // 拿到锁
                        System.out.println("线程1 获取到了锁1");
                        Thread.sleep(new Random().nextInt(1000));

                        if(lock2.tryLock(800,TimeUnit.MILLISECONDS)){
                            System.out.println("线程1 获取到了锁2");
                            System.out.println("线程1获取2把锁");

                            lock2.unlock();
                            lock1.unlock();
                            break;
                        }else{
                            System.out.println("线程1获取锁2失败, 已重试");


                            // 这里要还锁1
                            lock1.unlock();
                            Thread.sleep(new Random().nextInt(1000));
                        }
                    }else{
                        System.out.println("线程1获取锁1失败, 已重试");
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            if(flag==0){
                try {
                    if(lock2.tryLock(3000, TimeUnit.MILLISECONDS)){
                        // 拿到锁
                        System.out.println("线程2 获取到了锁2");
                        Thread.sleep(new Random().nextInt(1000));

                        if(lock1.tryLock(3000,TimeUnit.MILLISECONDS)){
                            System.out.println("线程2 获取到了锁1");
                            System.out.println("线程2获取2把锁");

                            lock1.unlock();
                            lock2.unlock();
                            break;
                        }else{
                            System.out.println("线程2获取锁1失败, 已重试");


                            // 这里要还锁1
                            lock2.unlock();
                            Thread.sleep(new Random().nextInt(1000));
                        }
                    }else{
                        System.out.println("线程2获取锁2失败, 已重试");
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
